package com.tbsoft.ehr.service.attendance;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.opensymphony.xwork2.ActionContext;
import com.tbsoft.ehr.dao.attendance.ReportDao;
import com.tbsoft.ehr.model.AttendanceReport;
import com.tbsoft.ehr.service.common.WorkdayService;
import com.tbsoft.ehr.util.ConfigProps;
/**
 * @desc 考勤报表
 * @author vastdream
 *
 */
public class ReportServiceImpl implements ReportService {
	private static final String LatterID= (String) ConfigProps.getContextProperty("ehr.public.attend.later");
	private ReportDao reportDao;
	private Log log = LogFactory.getLog(getClass());
	public synchronized void setReportDao(ReportDao reportDao) {
		this.reportDao = reportDao;
	}

	@Override
	public List<AttendanceReport> getAttendacneInfo(String dateStart,String dateEnd, String name)  {
		log.info("getAttendacneInfo start....");
		List<AttendanceReport> rtList = new ArrayList<AttendanceReport>();
		try{
			List<AttendanceReport> list = reportDao.getsearchUserList(dateStart,dateEnd,name,null);
			DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
			
			List<Date> fWorkdateList =workdayService.getWorkDays(df.parse(dateStart),df.parse(dateEnd) , "F");
			List<Date> mWorkdateList =workdayService.getWorkDays(df.parse(dateStart),df.parse(dateEnd) , "M");
			for(int i=0,len=list.size();i<len;i++){
				AttendanceReport ar = list.get(i);
				
				ar.setPayloadHours(ar.getNormalHours().subtract(ar.getLeaveHours()));
				
				List<Date> workList = (ar.getSex().equals("F") ? fWorkdateList:mWorkdateList);
				if(ar.getDate() == null){
					ar.setDate(workList.get(0));
				}else if (ar.getDate().compareTo(workList.get(0)) > 0){
					AttendanceReport preAr = i>0 ? list.get(i-1) : null;
					if(preAr == null || (preAr != null && !preAr.getUserId().equals(ar.getUserId()))){
						for(Date wdt:workList){
							if(wdt.before(ar.getDate())){
								AttendanceReport lar = (AttendanceReport) ar.clone();
								lar.setDate(wdt);
								lar.setPayloadHours(lar.getNormalHours());
								lar.setLeaveHours(null);
								rtList.add(lar);
							}else{
								break;
							}
						}
					}
				}
				rtList.add(ar);
				AttendanceReport nextAr = i+1 <len ? list.get(i+1) : null;
				if(nextAr != null && nextAr.getUserId().equals(ar.getUserId())){
					for(Date wdt : workList){
						if(wdt.after(ar.getDate()) && wdt.before(nextAr.getDate())){
							AttendanceReport lar = (AttendanceReport) ar.clone();
							lar.setDate(wdt);
							lar.setPayloadHours(lar.getNormalHours());
							lar.setLeaveHours(null);
							rtList.add(lar);
						}
					}
				}else if (nextAr == null || (nextAr != null && !nextAr.getUserId().equals(ar.getUserId()))){
					for(Date wdt:workList){
						if(wdt.after(ar.getDate())){
							AttendanceReport lar = (AttendanceReport) ar.clone();
							lar.setDate(wdt);
							lar.setPayloadHours(lar.getNormalHours());
							lar.setLeaveHours(null);
							rtList.add(lar);
						}
					}
				}
			}
		}catch(Exception e){
			log.error("exception:", e);
		}
		log.info("getAttendacneInfo end....");
		return rtList;
		
	}
	@SuppressWarnings({"unchecked" })
	@Override
	public List<AttendanceReport> getAttendacneReport(String dateStart,String dateEnd,String scId) {
		log.info("getAttendacneReport start....");
		List<AttendanceReport> rtList = new ArrayList<AttendanceReport>(200);
		try{
			Map<String, Map> attendMap = (Map<String, Map>) (pubFieldMap.get("ATTEND_TYPE"));
			List<AttendanceReport> list = reportDao.getsearchUserList(dateStart,dateEnd,null,scId);
			DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
			List<Date> fWorkdateList =workdayService.getWorkDays(df.parse(dateStart),df.parse(dateEnd) , "F");
			List<Date> mWorkdateList =workdayService.getWorkDays(df.parse(dateStart),df.parse(dateEnd) , "M");
			for(int i=0,len=list.size();i<len;i++){
				AttendanceReport ar = list.get(i);
				List<Date> workList = (ar.getSex().equals("F") ? fWorkdateList:mWorkdateList);
				BigDecimal norMalHours= ar.getNormalHours().multiply(new BigDecimal(workList.size()));
				ar.setNormalHours(norMalHours);
				ar.setLateHits(0);
				for(Entry<?,?> entry:attendMap.entrySet()){
					ar.pubLevaeMap((String)entry.getKey(), new BigDecimal(0));
				}
				//出满勤
				if(ar.getDate() == null){
					ar.setDate(df.parse(dateStart));
					ar.setPayloadHours(norMalHours);
				}else{ //有请假
					ar.pubLevaeMap(ar.getAdType(), ar.getLeaveHours());
					if(ar.getAdType().equals(LatterID)){
						ar.setLateHits(1);
					}
					while( i+1 < len && list.get(i+1).getUserId().equals(ar.getUserId())){
						AttendanceReport nextAr = list.get(++i);
						BigDecimal tmpAdHours = ar.getLeaveValue(nextAr.getAdType());
						tmpAdHours = tmpAdHours.add(nextAr.getLeaveHours());
						ar.pubLevaeMap(nextAr.getAdType(), tmpAdHours);
						if(nextAr.getAdType().equals(LatterID)){
							ar.setLateHits(1+ar.getLateHits());
						}
					}
					ar.setPayloadHours(norMalHours.subtract(ar.getLeaveTotVaule()));
				}
				rtList.add(ar);
			}
		}catch(Exception e){
			log.error("getAttendacneReport exception:",e);
		}
		log.info("getAttendacneReport end....");
		return rtList;
	}
	
	private WorkdayService workdayService;
	
	private Map<?,?> pubFieldMap;

	public synchronized WorkdayService getWorkdayService() {
		return workdayService;
	}

	public synchronized void setWorkdayService(WorkdayService workdayService) {
		this.workdayService = workdayService;
	}
	@Override
	public void setPubFieldMap(Map<?, ?> map) {
		pubFieldMap = map;
	}
	

}
